#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

// 待办事项结构体
typedef struct TodoItem {
    int id;                 // 唯一ID（用于哈希表查找）
    char content[100];      // 待办内容
    int priority;           // 优先级（1-5，5最高）
    time_t createTime;      // 创建时间
    int isCompleted;        // 是否完成（0-未完成，1-已完成）
    struct TodoItem* next;  // 链表指针（用于串联所有待办）
} TodoItem;

// 哈希表节点（用于快速查找待办）
typedef struct HashNode {
    int id;
    TodoItem* todo;         // 指向对应的待办事项
    struct HashNode* next;  // 解决哈希冲突（链表法）
} HashNode;

// 待办管理器（整合所有数据结构）
typedef struct {
    TodoItem* head;         // 链表头（存储所有待办）
    HashNode** hashTable;   // 哈希表（快速查找）
    int hashSize;           // 哈希表大小
    int nextId;             // 下一个可用ID
} TodoManager;

// 初始化待办管理器
TodoManager* initTodoManager(int hashSize) {
    TodoManager* manager = (TodoManager*)malloc(sizeof(TodoManager));
    if (!manager) return NULL;

    manager->head = NULL;
    manager->hashSize = hashSize;
    manager->nextId = 1;  // ID从1开始

    // 初始化哈希表
    manager->hashTable = (HashNode**)calloc(hashSize, sizeof(HashNode*));
    if (!manager->hashTable) {
        free(manager);
        return NULL;
    }

    return manager;
}

// 哈希函数（简单取模）
int hashFunction(int id, int hashSize) {
    return id % hashSize;
}

// 添加待办事项
void addTodo(TodoManager* manager, const char* content, int priority) {
    if (!manager || !content || priority < 1 || priority > 5) return;

    // 1. 创建新待办节点（链表）
    TodoItem* newItem = (TodoItem*)malloc(sizeof(TodoItem));
    if (!newItem) return;

    newItem->id = manager->nextId++;
    strncpy(newItem->content, content, 99);
    newItem->priority = priority;
    newItem->createTime = time(NULL);  // 获取当前时间
    newItem->isCompleted = 0;
    newItem->next = NULL;

    // 2. 插入链表头部（简化操作）
    newItem->next = manager->head;
    manager->head = newItem;

    // 3. 添加到哈希表（用于快速查找）
    int index = hashFunction(newItem->id, manager->hashSize);
    HashNode* hashNode = (HashNode*)malloc(sizeof(HashNode));
    if (hashNode) {
        hashNode->id = newItem->id;
        hashNode->todo = newItem;
        hashNode->next = manager->hashTable[index];  // 头插法
        manager->hashTable[index] = hashNode;
    }

    printf("添加成功！ID: %d\n", newItem->id);
}

// 哈希表查找待办
TodoItem* findTodoById(TodoManager* manager, int id) {
    if (!manager || id < 1) return NULL;

    int index = hashFunction(id, manager->hashSize);
    HashNode* cur = manager->hashTable[index];
    while (cur) {
        if (cur->id == id) {
            return cur->todo;  // 找到返回待办
        }
        cur = cur->next;
    }
    return NULL;  // 未找到
}

// 标记待办为完成
void completeTodo(TodoManager* manager, int id) {
    TodoItem* todo = findTodoById(manager, id);
    if (todo) {
        todo->isCompleted = 1;
        printf("已标记完成：%s\n", todo->content);
    } else {
        printf("未找到ID为%d的待办\n", id);
    }
}

// 删除待办事项
void deleteTodo(TodoManager* manager, int id) {
    if (!manager || id < 1) return;

    // 1. 从链表中删除
    TodoItem* prev = NULL;
    TodoItem* cur = manager->head;
    while (cur) {
        if (cur->id == id) {
            if (prev) {
                prev->next = cur->next;  // 中间节点
            } else {
                manager->head = cur->next;  // 头节点
            }
            break;
        }
        prev = cur;
        cur = cur->next;
    }

    if (!cur) {  // 未找到
        printf("未找到ID为%d的待办\n", id);
        return;
    }

    // 2. 从哈希表中删除
    int index = hashFunction(id, manager->hashSize);
    HashNode* hPrev = NULL;
    HashNode* hCur = manager->hashTable[index];
    while (hCur) {
        if (hCur->id == id) {
            if (hPrev) {
                hPrev->next = hCur->next;
            } else {
                manager->hashTable[index] = hCur->next;
            }
            free(hCur);  // 释放哈希节点
            break;
        }
        hPrev = hCur;
        hCur = hCur->next;
    }

    // 3. 释放待办节点
    free(cur);
    printf("已删除ID为%d的待办\n", id);
}

// 按优先级排序（冒泡排序，简化实现）
void sortByPriority(TodoManager* manager) {
    if (!manager || !manager->head) return;

    int swapped;
    TodoItem* ptr1;
    TodoItem* lptr = NULL;

    do {
        swapped = 0;
        ptr1 = manager->head;

        while (ptr1->next != lptr) {
            // 优先级高的放前面（5 > 4 > ...）
            if (ptr1->priority < ptr1->next->priority) {
                // 交换节点数据（简化操作，不交换指针）
                TodoItem temp = *ptr1;
                *ptr1 = *(ptr1->next);
                *(ptr1->next) = temp;
                swapped = 1;
            }
            ptr1 = ptr1->next;
        }
        lptr = ptr1;
    } while (swapped);

    printf("已按优先级排序\n");
}

// 显示所有待办
void showAllTodos(TodoManager* manager) {
    if (!manager || !manager->head) {
        printf("暂无待办事项\n");
        return;
    }

    printf("\n===== 所有待办事项 =====\n");
    TodoItem* cur = manager->head;
    while (cur) {
        const char* status = cur->isCompleted ? "[已完成]" : "[未完成]";
        char timeStr[20];
        strftime(timeStr, 20, "%Y-%m-%d %H:%M", localtime(&cur->createTime));

        printf("ID: %d\n", cur->id);
        printf("内容: %s\n", cur->content);
        printf("优先级: %d (5最高)\n", cur->priority);
        printf("创建时间: %s\n", timeStr);
        printf("状态: %s\n", status);
        printf("------------------------\n");

        cur = cur->next;
    }
}

// 释放所有资源
void freeTodoManager(TodoManager* manager) {
    if (!manager) return;

    // 释放链表
    TodoItem* cur = manager->head;
    while (cur) {
        TodoItem* temp = cur;
        cur = cur->next;
        free(temp);
    }

    // 释放哈希表
    for (int i = 0; i < manager->hashSize; i++) {
        HashNode* hCur = manager->hashTable[i];
        while (hCur) {
            HashNode* temp = hCur;
            hCur = hCur->next;
            free(temp);
        }
    }
    free(manager->hashTable);
    free(manager);
}

// 显示菜单
void showMenu() {
    printf("\n===== 待办事项管理系统 =====\n");
    printf("1. 添加待办\n");
    printf("2. 标记完成\n");
    printf("3. 删除待办\n");
    printf("4. 按优先级排序\n");
    printf("5. 查看所有待办\n");
    printf("0. 退出\n");
    printf("请选择操作: ");
}

int main() {
    // 初始化管理器（哈希表大小设为10）
    TodoManager* manager = initTodoManager(10);
    if (!manager) {
        printf("初始化失败\n");
        return 1;
    }

    int choice;
    do {
        showMenu();
        scanf("%d", &choice);
        getchar();  // 吸收换行符

        switch (choice) {
            case 1: {
                char content[100];
                int priority;
                printf("请输入待办内容: ");
                fgets(content, 100, stdin);
                content[strcspn(content, "\n")] = '\0';  // 去除换行符

                printf("请输入优先级(1-5): ");
                scanf("%d", &priority);
                addTodo(manager, content, priority);
                break;
            }
            case 2: {
                int id;
                printf("请输入要标记完成的ID: ");
                scanf("%d", &id);
                completeTodo(manager, id);
                break;
            }
            case 3: {
                int id;
                printf("请输入要删除的ID: ");
                scanf("%d", &id);
                deleteTodo(manager, id);
                break;
            }
            case 4:
                sortByPriority(manager);
                break;
            case 5:
                showAllTodos(manager);
                break;
            case 0:
                printf("谢谢使用，再见！\n");
                break;
            default:
                printf("无效操作，请重新选择\n");
        }
    } while (choice != 0);

    // 释放资源
    freeTodoManager(manager);
    return 0;
}
